package com.woniuxy.threadpool;


import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

/**
 * <P> @Author: ideaAdmin
 * <P> TODO: Class
 * <P> TODO: ForkJoin线程池
 * <P> Date: 2022/4/10:20:53
 * <P> Description:
 */
@Slf4j(topic = "c.c")
public class ForkJoinPoolTest {
    public static void main(String[] args) {
        ForkJoinPool pool = new ForkJoinPool(4);
        //System.out.println(pool.invoke(new MyTask02(1, 5)));
        System.out.println(pool.invoke(new MyTask(5)));
        //TODO new MyTask(5) -> new MyTask(4) ->new MyTask(3) -> new MyTask(2)  -> new MyTask(1)
    }
}

/**
 * TODO:求1-n的整数和
 **/
@Slf4j(topic = "c.c")
class MyTask extends RecursiveTask<Long> {
    private int n;


    public MyTask(int n) {
        this.n = n;
    }

    @Override
    protected Long compute() {
        //TODO 设置终止条件
        if (n == 1) {
            log.debug("join() {}", n);
            return 1L;
        }
        MyTask t1 = new MyTask(n - 1);

        //TODO 让一个线程去执行任务
        t1.fork();
        log.debug("fork() {} + {}", n, t1);

        //TODO 获取并合并任务结果
        long result = n + t1.join();
        log.debug("join() {} + {} = {}", n, t1.join(), result);


        return result;
    }

    @Override
    public String toString() {
        return "" + n;
    }
}


/**
 * TODO:求1-n的整数和
 **/
@Slf4j(topic = "c.c")
class MyTask02 extends RecursiveTask<Long> {
    private long begin;
    private long end;


    public MyTask02(long begin, long end) {
        this.begin = begin;
        this.end = end;
    }

    @Override
    protected Long compute() {
        //TODO 设置终止条件

        if (begin == end) {
            log.debug("join() {}", begin);
            return begin;
        }
        if (end - begin == 1) {
            log.debug("join() {} + {} = {}", begin, end, end + begin);
            return end + begin;
        }
        //TODO 分成两部分来处理
        long mid = begin + end / 2;
        MyTask02 t1 = new MyTask02(begin, mid);
        t1.fork();

        MyTask02 t2 = new MyTask02(mid + 1, end);
        t2.fork();

        log.debug("fork() {} + {} = ?", t1, t2);

        long result = t1.join() + t2.join();
        log.debug("join() ({})+ ({}) = {}", t1, t2, result);
        return result;
    }

    @Override
    public String toString() {
        return "" + begin +
                ", " + end;
    }
}